package com.mobile.check.present;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.os.SystemClock;
import android.support.v4.content.FileProvider;
import android.view.View;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import cn.droidlover.xdroidmvp.kit.Kits;
import cn.droidlover.xdroidmvp.kit.NLog;
import cn.droidlover.xdroidmvp.kit.NToast;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;
import com.mobile.check.activitys.Home2Activity;
import com.mobile.check.beans.BluetoothInfo;
import com.mobile.check.beans.TaskInfo;
import com.mobile.check.beans.TaskItemInfo;
import com.mobile.check.app.R;
import com.mobile.check.db.EntityManager;
import com.mobile.check.util.ScanUtil;
import com.mobile.check.util.ZipUtils;

/**
 * 类名: HomePresent
 * 作者: 李学伟
 * 日期: 2020年10月13日 11:12
 * 描述:
 */
public class Home2Present extends BasePresent<Home2Activity> {
    String sRoot;
    private final String checkPath = "检测系统/本地任务/检测任务";
    private final String repeatCheckPath = "检测系统/本地任务/复检任务";
    private final String trailCheckPath = "检测系统/本地任务/跟踪任务";
    private final String exportPath = "检测系统/数据导出/";
    private final String picPath = "检测系统/本地任务/图片/";

    private BluetoothAdapter mBT = BluetoothAdapter.getDefaultAdapter();
    /**
     * 保存蓝牙进入前的开启状态
     */
    private boolean mbBleStatusBefore = false;
    public boolean hadImportScanBag;


    public void init() {
        getV().showLoadDialog();
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            sRoot = Environment.getExternalStorageDirectory().getAbsolutePath();//获取跟目录
            markDir("检测系统/");
            markDir("检测系统/备份/");
            markDir("检测系统/本地任务/");
            markDir("检测系统/本地任务/检测任务/");
            markDir("检测系统/本地任务/复检任务/");
            markDir("检测系统/本地任务/跟踪任务/");
            markDir("检测系统/本地任务/图片/");

            markDir("检测系统/网络任务/");
            markDir("检测系统/网络任务/检测任务/");
            markDir("检测系统/网络任务/复检任务/");
            markDir("检测系统/网络任务/跟踪任务/");
            markDir("检测系统/网络任务/图片/");
            markDir("检测系统/错误日志/");
            markDir("检测系统/扫一扫/");
            markDir("检测系统/数据导出/");
        }

        Observable.create(new ObservableOnSubscribe<Boolean>() {
            @Override
            public void subscribe(ObservableEmitter<Boolean> e) throws Exception {
                moveFile("检测系统/检测任务", "检测系统/本地任务/检测任务");
                moveFile("检测系统/复检任务", "检测系统/本地任务/复检任务");
                moveFile("检测系统/跟踪任务", "检测系统/本地任务/跟踪任务");
                moveFile("检测系统/图片", "检测系统/本地任务/图片");
                e.onNext(true);
                e.onComplete();
            }
        }).flatMap(new Function<Boolean, ObservableSource<TaskInfo>>() {
            @Override
            public ObservableSource<TaskInfo> apply(Boolean aBoolean) throws Exception {
                List<TaskInfo> list = EntityManager.getInstance().queryTaskInfo();
                return Observable.fromIterable(list);
            }
        }).filter(new Predicate<TaskInfo>() {
            @Override
            public boolean test(TaskInfo taskInfo) throws Exception {
                NLog.d("Home2Present", "newXmlPath = " + taskInfo.toString());
                return taskInfo.isLocalFile();
            }
        }).map(new Function<TaskInfo, TaskInfo>() {
            @Override
            public TaskInfo apply(TaskInfo taskInfo) throws Exception {
                String filePath = taskInfo.getTaskFilePath();
                NLog.d("Home2Present", "filePath = " + filePath);
                if (Kits.File.isFileExist(filePath) && !filePath.contains("本地任务")) {
                    File file = new File(filePath);
                    String oldPath = file.getPath();
                    String newPath = oldPath.replace("检测系统", "检测系统/本地任务");
                    taskInfo.setTaskFilePath(newPath);
                    EntityManager.getInstance().saveTaskInfo(taskInfo);
                }
                return taskInfo;
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<TaskInfo>() {
            @Override
            public void accept(TaskInfo o) {
                NLog.d("Home2Present", "accept = " + o.toString());
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) {
                NLog.d("Home2Present", "accept = " + throwable.toString());
                throwable.printStackTrace();
                getV().disLoadDialog();
            }
        }, new Action() {
            @Override
            public void run() {
                NLog.d("Home2Present", "Action = ");
                getV().disLoadDialog();
            }
        });

    }

    private void markDir(String dir) {
        sRoot = Environment.getExternalStorageDirectory().getAbsolutePath();//获取跟目录
        StringBuilder dirBuilder = new StringBuilder(sRoot);
        dirBuilder.append(File.separator).append(dir);
        Kits.File.makeFolders(dirBuilder.toString());
    }

    private void moveFile(String oldDir, String newDir) {
        sRoot = Environment.getExternalStorageDirectory().getAbsolutePath();//获取跟目录
        oldDir = sRoot + File.separator + oldDir;
        NLog.d("Home2Present", "oldDir = " + oldDir);
        newDir = sRoot + File.separator + newDir;
        NLog.d("Home2Present", "newDir = " + newDir);
        NLog.d("Home2Present", "exist = " + Kits.File.isFolderExist(oldDir));
        if (Kits.File.isFolderExist(oldDir)) {
            File[] childList = new File(oldDir).listFiles();
            NLog.d("Home2Present", "childList = " + childList.length);
            for (File file : childList) {
                NLog.d("Home2Present", "filePath = " + file.getPath());
                if (Kits.File.isFileExist(file.getPath())) {
                    String fileName = file.getName();
                    String newPath = newDir + File.separator + fileName;
                    NLog.d("Home2Present", "newXmlPath = " + newPath);
                    Kits.File.moveFile(file.getPath(), newPath);
                }
            }
        }
    }


    private File[] getZipFiles(String dirPath) {
        File zipDir = new File(dirPath);
        File[] files = zipDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                if (pathname.getPath().endsWith(".zip")) {
                    return true;
                }
                return false;
            }
        });
        return files;
    }


    public void checkZip() {

        getV().showLoading(View.VISIBLE);
        sRoot = Environment.getExternalStorageDirectory().getAbsolutePath();//获取跟目录
        final String picPath2 = sRoot + File.separator + picPath;
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> e) throws Exception {
                String checkPath2 = sRoot + File.separator + checkPath;
                File[] files = getZipFiles(checkPath2);
                for (File file : files) {
                    ZipUtils.UnZipFolder(file.getPath(), checkPath2, picPath2);
                    Kits.File.deleteFile(file.getPath());
                }
                checkPath2 = sRoot + File.separator + repeatCheckPath;
                files = getZipFiles(checkPath2);
                for (File file : files) {
                    ZipUtils.UnZipFolder(file.getPath(), checkPath2, picPath2);
                    Kits.File.deleteFile(file.getPath());
                }
                checkPath2 = sRoot + File.separator + trailCheckPath;
                files = getZipFiles(checkPath2);
                for (File file : files) {
                    ZipUtils.UnZipFolder(file.getPath(), checkPath2, picPath2);
                    Kits.File.deleteFile(file.getPath());
                }
                e.onNext(1);
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {
                getV().showLoading(View.GONE);
                startBlue();
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                throwable.printStackTrace();
                getV().showLoading("ZIP文件存在错误，请重新导入后,点击此处加载！");
                getV().disLoadDialog();
            }
        }, new Action() {
            @Override
            public void run() throws Exception {

            }
        });

//        oldDir = sRoot + File.separator + oldDir;
    }

    public void write(String content) {
        String name = Kits.Date.getyyyyMMddHH(Calendar.getInstance().getTimeInMillis());
        String time = Kits.Date.getYmdhms3(Calendar.getInstance().getTimeInMillis());
        String fileName = "蓝牙" + name + ".txt";
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            String crashDir = Environment.getExternalStorageDirectory() + "/监测点系统日志/";
            Kits.File.writeFile(crashDir + fileName, "\n" + time + ":" + content, true);
        }
    }

    public void install() {
        if (copyApkFromAssets("pojie.apk", Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.apk")) {
            AlertDialog.Builder m = new AlertDialog.Builder(getV())
                    .setMessage("是否安装破解版？")
                    .setPositiveButton("yes", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            String apkFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.apk";
                            File apkfile = new File(apkFile);
                            Intent intent = new Intent(Intent.ACTION_VIEW);
                            if (!apkfile.exists()) {
                                return;
                            }
                            //判断是否是AndroidN以及更高的版本
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                try {
                                    String ss = "com.mobile.check.app.fileprovider";
                                    Uri contentUri = FileProvider.getUriForFile(getV().getApplicationContext(), ss, apkfile);
                                    intent.setAction(Intent.ACTION_VIEW);
                                    intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            } else {
                                intent.setDataAndType(Uri.fromFile(apkfile), "application/vnd.android.package-archive");
                                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            }
                            try {
                                getV().startActivity(intent);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
            m.show();
        }
    }


    public boolean copyApkFromAssets(String fileName, String path) {
        boolean copyIsFinish = false;
        try {
            InputStream is = getV().getAssets().open(fileName);
            File file = new File(path);
            file.createNewFile();
            FileOutputStream fos = new FileOutputStream(file);
            byte[] temp = new byte[1024];
            int i = 0;
            while ((i = is.read(temp)) > 0) {
                fos.write(temp, 0, i);
            }
            fos.close();
            is.close();
            copyIsFinish = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return copyIsFinish;
    }


    public void startBlue() {
        new startBluetoothDeviceTask().execute(""); //启动蓝牙设备
    }

    /*多线程处理(开机时启动蓝牙)*/
    private class startBluetoothDeviceTask extends AsyncTask<String, String, Integer> {
        /**
         * 常量:蓝牙已经启动
         */
        private static final int RET_BULETOOTH_IS_START = 0x0001;
        /**
         * 常量:设备启动失败
         */
        private static final int RET_BLUETOOTH_START_FAIL = 0x04;
        /**
         * 等待蓝牙设备启动的最长时间(单位S)
         */
        private static final int miWATI_TIME = 15;
        /**
         * 每次线程休眠时间(单位ms)
         */
        private static final int miSLEEP_TIME = 150;
        /**
         * 进程等待提示框
         */
        private ProgressDialog mpd;
        BluetoothAdapter mBT = BluetoothAdapter.getDefaultAdapter();

        /**
         * 线程启动初始化操作
         */
        @Override
        public void onPreExecute() {
            /*定义进程对话框*/
            mpd = new ProgressDialog(getV());
            mpd.setMessage(getV().getString(R.string.actDiscovery_msg_starting_device));//蓝牙启动中
            mpd.setCancelable(false);//不可被终止
            mpd.setCanceledOnTouchOutside(false);//点击外部不可终止
            mpd.show();
            mbBleStatusBefore = mBT.isEnabled(); //保存进入前的蓝牙状态
        }

        /**
         * 异步的方式启动蓝牙，如果蓝牙已经启动则直接进入扫描模式
         */
        @Override
        protected Integer doInBackground(String... arg0) {
            int iWait = miWATI_TIME * 1000;//倒减计数器
            /* BT isEnable */
            if (!mBT.isEnabled()) {
                mBT.enable(); //启动蓝牙设备
                //等待miSLEEP_TIME秒，启动蓝牙设备后再开始扫描
                while (iWait > 0) {
                    if (!mBT.isEnabled())
                        iWait -= miSLEEP_TIME; //剩余等待时间计时
                    else
                        break; //启动成功跳出循环
                    SystemClock.sleep(miSLEEP_TIME);
                }
                if (iWait < 0) //表示在规定时间内,蓝牙设备未启动
                    return RET_BLUETOOTH_START_FAIL;
            }
            return RET_BULETOOTH_IS_START;
        }

        /**
         * 阻塞任务执行完后的清理工作
         */
        @Override
        public void onPostExecute(Integer result) {
            if (mpd.isShowing())
                mpd.dismiss();//关闭等待对话框

            if (RET_BLUETOOTH_START_FAIL == result) {    //蓝牙设备启动失败
                AlertDialog.Builder builder = new AlertDialog.Builder(getV()); //对话框控件
                builder.setTitle(getV().getString(R.string.dialog_title_sys_err));//设置标题
                builder.setMessage(getV().getString(R.string.actDiscovery_msg_start_bluetooth_fail));
                builder.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        mBT.disable();
                        NToast.shortToast("请手动开启蓝牙");
                    }
                });
                builder.create().show();
            } else if (RET_BULETOOTH_IS_START == result) {    //蓝牙启动成功
                getConnectBt();
            }
        }
    }


    private void setConnectDevice(BluetoothDevice device) {
        BluetoothInfo info = new BluetoothInfo(device.getName(), device.getAddress());
        if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
            info.setBond(getV().getString(R.string.actDiscovery_bond_bonded));
        } else {
            info.setBond(getV().getString(R.string.actDiscovery_bond_nothing));
        }
        getV().setCurrentDevice(info);
    }


    private void getConnectBt() {
        int a2dp = mBT.getProfileConnectionState(BluetoothProfile.A2DP);
        int headset = mBT.getProfileConnectionState(BluetoothProfile.HEADSET);
        int health = mBT.getProfileConnectionState(BluetoothProfile.HEALTH);
        int flag = -1;
        if (a2dp == BluetoothProfile.STATE_CONNECTED) {
            flag = a2dp;
        } else if (headset == BluetoothProfile.STATE_CONNECTED) {
            flag = headset;
        } else if (health == BluetoothProfile.STATE_CONNECTED) {
            flag = health;
        }
        if (flag != -1) {
            mBT.getProfileProxy(getV(), new BluetoothProfile.ServiceListener() {
                @Override
                public void onServiceDisconnected(int profile) {
                }

                @Override
                public void onServiceConnected(int profile, BluetoothProfile proxy) {
                    List<BluetoothDevice> mDevices = proxy.getConnectedDevices();
                    if (mDevices != null && mDevices.size() > 0) {
                        for (BluetoothDevice device : mDevices) {
                            NLog.d("xxx", device.getName() + "," + device.getAddress());
                        }
                        setConnectDevice(mDevices.get(0));
                    }
                }
            }, flag);
        }
    }


    public void ondestory() {
//检查如果进入前蓝牙是关闭的状态，则退出时关闭蓝牙
        if (null != mBT && !this.mbBleStatusBefore)
            mBT.disable();

    }

    public void exportDatas() {
        getV().showLoadDialog();
        List<TaskInfo> taskInfos = EntityManager.getInstance().queryTaskInfo();
        for (TaskInfo taskInfo : taskInfos) {
            String sourceFilePath = taskInfo.getTaskFilePath();
            File file = new File(sourceFilePath);
            if (Kits.File.isFileExist(sourceFilePath)) {
                String dir = Kits.File.getFolderName(sourceFilePath);
                String tarDir = dir.replace("本地任务", "数据导出").replace("网络任务", "数据导出");
                Kits.File.makeFolders(tarDir);
                File newFile = new File(tarDir,file.getName());
                if (newFile.exists()) {
                    newFile.delete();
                }
                Kits.File.copyFile(sourceFilePath,newFile.getPath());
            }
        }
        getV().disLoadDialog();
        getV().showToast("导出完毕");

    }

    public boolean ishadImportScanBag(){
        return hadImportScanBag;
    }

    public void checkScanFile(){
        ScanUtil scanUtil = new ScanUtil(getV());
        scanUtil.unZip(new Observer<Boolean>() {
            @Override
            public void onSubscribe( Disposable d) {
                
            }

            @Override
            public void onNext( Boolean o) {
                hadImportScanBag = o;
                getV().toScan();
            }

            @Override
            public void onError( Throwable e) {
                hadImportScanBag = false;
                e.printStackTrace();
                getV().inportFail();
            }

            @Override
            public void onComplete() {

            }
        });
        
        
    }

    public void backUpDatas() {
        getV().showLoadDialog();
        List<TaskInfo> taskInfos = EntityManager.getInstance().queryTaskInfo();
        List<File> fileList = new ArrayList<>();
        List<TaskItemInfo> itemInfoList = new ArrayList<>();
        JsonArray jsonArray = new JsonArray();
        for (TaskInfo taskInfo : taskInfos) {
            File excelFile = new File(taskInfo.getTaskFilePath());
            if (!excelFile.exists()) {
                continue;
            }
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("task_name", taskInfo.getTask_name());
            jsonObject.addProperty("taskFilePath", taskInfo.getTaskFilePath());
            jsonObject.addProperty("isLocalFile", taskInfo.getIsLocalFile());
            jsonObject.addProperty("taskType", taskInfo.getTaskType());
            jsonObject.addProperty("_ID", taskInfo.get_ID());
            jsonArray.add(jsonObject);

            List<TaskItemInfo> checkList = EntityManager.getInstance().queryTaskItemInfoByParentId(taskInfo.get_ID());
            itemInfoList.addAll(checkList);

            fileList.add(new File(taskInfo.getTaskFilePath()));
        }
        Gson gson = new Gson();
        String deviceInfos = gson.toJson(jsonArray);

        String taskBackupPath = sRoot + File.separator + "检测系统/备份/" + "taskInfo.json";
        Kits.File.writeFile(taskBackupPath, deviceInfos, false);

        String itemInfos = gson.toJson(itemInfoList);
        String itemsFilePath = sRoot + File.separator + "检测系统/备份/" + "items.json";
        Kits.File.writeFile(itemsFilePath, itemInfos, false);
        File zipFile = new File(sRoot + File.separator + "检测系统/备份", Kits.Date.getYmdhms3(Calendar.getInstance().getTimeInMillis()) + ".zip");
        if (null != zipFile && zipFile.exists()) {
            zipFile.delete();
        }

        fileList.add(new File(taskBackupPath));
        fileList.add(new File(itemsFilePath));
        try {
            zipFile.createNewFile();
            ZipUtils.zipFiles(fileList, zipFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        getV().disLoadDialog();
        getV().showToast("备份完成");
    }


    public void startimport() {
//        getV().showLoadDialog();
//        Observable.create(new ObservableOnSubscribe<Object>() {
//            @Override
//            public void subscribe(ObservableEmitter<Object> e) throws Exception {
//                try {
//                    insertDatas();
//                    e.onNext(1);
//                    e.onComplete();
//                } catch (Exception exception) {
//                    exception.printStackTrace();
//                    e.onError(exception);
//                }
//
//
//            }
//        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Consumer<Object>() {
//                    @Override
//                    public void accept(Object o) throws Exception {
//                        getV().disLoadDialog();
//                    }
//                }, new Consumer<Throwable>() {
//                    @Override
//                    public void accept(Throwable throwable) throws Exception {
//                        throwable.printStackTrace();
//                    }
//                });


    }

    public boolean insertDatas() throws Exception{
        String dataDir = Environment.getExternalStorageDirectory() + "/" + getV().getString(R.string.app_name) + "/备份/";
        StringBuilder jsonBuilder = Kits.File.readFile(dataDir + "taskInfo.json", "utf-8");
        String json = jsonBuilder.toString();
        List<TaskInfo> taskInfoList = new ArrayList<>();

        JSONArray jsonArray = new JSONArray(json);
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            TaskInfo taskInfo = new TaskInfo();
            taskInfo.setTask_name(jsonObject.optString("task_name"));
            taskInfo.setTaskFilePath(jsonObject.optString("taskFilePath"));
            taskInfo.setIsLocalFile(true);
            taskInfo.setTask_name(jsonObject.optString("task_name"));
            taskInfo.setTaskType(0);
            taskInfo.set_ID(jsonObject.getLong("_ID"));
            taskInfoList.add(taskInfo);
        }
        EntityManager.getInstance().saveTaskInfo(taskInfoList);

        jsonBuilder = Kits.File.readFile(dataDir + "items.json", "utf-8");
        json = jsonBuilder.toString();
        Type type = new TypeToken<ArrayList<TaskItemInfo>>() {
        }.getType();
        ArrayList<TaskItemInfo> jsonObjects = new Gson().fromJson(json, type);
        EntityManager.getInstance().saveTaskItemInfo(jsonObjects);
        return true;
    }

}
